//
//  WmcHomeVM.swift
//  YPWatermarkCamera
//
//  Created by 赵新 on 2022/3/4.
//

import CoreGraphics
import RxRelay
import UIKit
import YPBedrock
import YPGraphicEngine
import AMapSearchKit

// MARK: - [WmcHomeVM]


open class WmcHomeVM: WmcBaseVM {
    
    typealias DelayTime = WmcDelayBtn.DelayTime
    
    // MARK: 输出

    /// 水印
    let watermarkRelay: BehaviorRelay<WmcWatermarkDetailModel> = .init(value: .init())
    
    // 拍照识物
    var recognitionModel: WmcWatermarkDetailModel?

    /// 图片处理完成
    let photoDisposeFinishRelay: PublishRelay<YPWmcManager.PhotoResult> = .init()

    /// 本地相册媒体集合
    var localMediaAlbumPhotoListRelay: BehaviorRelay<[WmcLocalMediaAlbumDBManager.DBModel]> = .init(value: [])

    /// 视频录制进度
    var videoRecordingProgressRelay: BehaviorRelay<CGFloat> = .init(value: 0)

    /// 视频已录制时间
    var videoRecordingTimeRelay: BehaviorRelay<String> = .init(value: "00:00")

    /// 视频需要停止录制
    var videoStopRecordingRelay: PublishRelay<Void> = .init()

    /// 视频录制结束
    var finishedRecordingVideo: PublishRelay<Void> = .init()

    /// 视频提示toast
    var videoRecordingTipsTostRelay: PublishRelay<Void> = .init()

    /// 更多权益
    var moreRightsRelay: PublishRelay<Void> = .init()

    /// 本地相册上传云相册
    var localPhotoUploadRelay: PublishRelay<Void> = .init()

    /// 弹出登录界面
    var showLoginRelay: PublishRelay<Void> = .init()

    /// 定位右下角提示消失
    let locationTipsDismiss: PublishRelay<Void> = .init()

    /// 定位右下角提示状态改变
    let locationTipsUnauthorized: PublishRelay<Void> = .init()

    /// 添加相机视图
    let addCameraViewRelay: PublishRelay<Void> = .init()

    // MARK: 业务输出

    /// 送积分业务线开启
    var business_integralRelay: BehaviorRelay<WmcIntegralModel?> = .init(value: nil)

    /// 送积分业务线-打卡天数
    var business_punchCardDayNumRelay: BehaviorRelay<Int> = .init(value: 0)

    // MARK: 其他
    /// 视频录制定时器
    var videoRecordTimer: Timer?
    
    /// 录制视频最大时长，秒
    var recordingMaxTenSeconds = 10 * 60

    /// 已录制视频的时长
    var recordingBeginTenSeconds: Int = 0
    
    /// 10秒弹窗是否显示过
    var isShowRecordingTenSecondToast = false
    
    
    /// 背景是否透明状态
    var isTransparent: Bool = false

    /// 功能模式
    var functionMode: WmcButtonItemType.HomeFunctionMode = .photo
    
    /// 拍照的画幅
    var photoAspectRatio: YPGESunglasses.AspectRatio = .ar_4_3
    
    /// 相机当前画幅比
    var currentAspectRatio: YPGESunglasses.AspectRatio = .ar_4_3
    
    /// 拍照的延时时间
    var delayTime: DelayTime = .none
    
    /// 分辨率级别, 默认标清
    var resolutionLevel: WmcResolution.Level = .standard
    
    /// 分辨率
    var resolution: WmcResolution {
        return WmcResolution(level: resolutionLevel, aspectRatio: photoAspectRatio)
    }
    /// 视频清晰度
    var articulation: YPGEVideoBuffer.Articulation = ._720p

    /// 视频录制状态
    var videoRecordState: WmcHomeVC.VideoRecordState = .stop

    /// 权限弹窗调度器
    let authorizedScheduler = WmcScheduler<Any>(identifier: "authorized")

    /// 未获取定位权限
    var locationNotAuthorized: (() -> Void)?
    
    /// 拍照/录视频保存图片/视频是否提示过相册权限
    var hasAlbumAuthorizationAlertForTakePhotoShown = false
    
    /// 设置支持的方向
    var defaultOrientation: [UIDeviceOrientation] = [
        .unknown, .portrait, .portraitUpsideDown, .landscapeLeft, .landscapeRight, .faceUp, .faceDown,
    ]
    
    var homeDelegate: WmcHomeDelegate? {
        return YPWmcManager.shared.uiDelegate.homeDelegate
    }
    
    /// 滤镜数据源
    private(set) lazy var filterItems: [WmcImageFilterItem] = {
        var items: [WmcImageFilterItem] = []
        // 原片
        let originItem = WmcImageFilterItem(name: "原片", image: "icon_filter_none".wmc_image)
        originItem.isOrigin = true
        items.append(originItem)
        // 饱和度
        let saturationItem = WmcImageFilterItem(name: "推荐1", image: "icon_filter_recommend".wmc_image)
        let saturationFilter = WmcSaturationFilter()
        saturationItem.filter = saturationFilter
        items.append(saturationItem)
        // LUT滤镜
        let lutImageNum: [Int] = [3, 14, 38, 39]
        for (index, num) in lutImageNum.enumerated() {
            let item = WmcImageFilterItem(name: "推荐\(index + 2)", image: "icon_filter_recommend".wmc_image)
            let lutImageName = String(format: "lut_%03d", num)
            let lutImage = lutImageName.wmc_image
            if lutImage.size == .zero { continue }
            let filter = WmcLUTFilter(lutImage: lutImage)
            item.filter = filter
            items.append(item)
        }
        // 默认选中
        if let name: String = WmcUserdefault.object(forKey: .State.Camera.filter),
           let item = items.first(where: { $0.name == name }) {
            item.isSelected = true
            selectedFilterItem = item
        } else {
            originItem.isSelected = true
            selectedFilterItem = originItem
        }
        return items
    }()
    /// 当前选中的滤镜
    var selectedFilterItem: WmcImageFilterItem?
    
    /// 是否显示二维码验证
    var showQrcodeVerify: Bool {
        return WmcPreferenceSettingsManager.shared.cameraSetting.qrcodeVerify
    }
    
    /// 是否显示过二维码用户引导
    var hasShowQRGuide: Bool {
        let shown: Bool = WmcUserdefault.object(forKey: .Tips.Home.hasShownQrVerifyGuide) ?? false
        return shown
    }
    
    /// 拼图设置
    lazy var combinePhotoSetting: WmcCombinePhotoSetting = {
        if let json: String = WmcUserdefault.object(forKey: .State.CombinePhoto.setting),
           let setting = WmcCombinePhotoSetting.deserialize(from: json) {
            return setting
        }
        return WmcCombinePhotoSetting()
    }()
    /// 已拍的带拼图图片
    lazy var combinedPhotos: [UIImage] = []
    
    /// (边拍边拼)最后一次拍照的水印信息
    var lastWatermarkModel: WmcWatermarkDetailModel?
    
    /// 是否已完成边拍边拼用户引导
    var hasCombinePhotoGuideFinished: Bool {
        let shown: Bool = WmcUserdefault.object(forKey: .Tips.Home.hasCombinePhotoGuideFinished) ?? false
        return shown
    }
    
    /// 是否进行过拼图引导(弹出过拼图引导弹窗)
    var hasCombinePhotoGuided: Bool = false
    
    /// 各个功能下的闪光灯模式
    lazy var flashModes: [String: YPGECamera.FlashMode] = [:]

    // MARK: 加载

    func loadData() {
        // 同步本地相册列表
        syncLocalAlbumList()
    }

    // MARK: 输入

    /// 获取上一次使用的水印
    func getLastUseWatermark() {
        // 查找记录
        readLastUseWatermark() { [weak self] wmModel in
            guard let weakSelf = self else { return }
            if let wmModel = wmModel, // 也找到了这个
               wmModel.wmId != 0
            {
                weakSelf.setWatermarkModel(wmModel)
            }
            let watermarkGroupType = YPWmcManager.shared.watermarkGroupType
            WmcMediaWatermarkAPI.fetchWatermarkList(watermarkIds: watermarkGroupType.info.templateIds, success: { [weak self] list in
                guard let weakSelf = self else { return }
                
                weakSelf.homeDelegate?.watermarkListDidLoad(.current, list: list)
                
                // 查找后台是否还开启这个水印
                var isServiceUseWatermark = false
                for classify in list {
                    for watermark in classify.watermarks {
                        if watermark.wmId == wmModel?.wmId { // 有并且在使用
                            isServiceUseWatermark = true
                        }
                    }
                }
                // 决策使用缓存还是第一个
                if isServiceUseWatermark, // 后台有这个水印
                   let wmModel = wmModel, // 也找到了这个
                   wmModel.wmId != 0
                {
                    weakSelf.setDefaultWatermark(wmModel, classifyList: list)
                } else { // 没有记录，则使用所有水印的第一条
                    guard let weakSelf = self,
                          let firstClassify = list.first,
                          let firstWm = firstClassify.watermarks.first else { return }
                    // 设置水印、切换水印、记录水印
                    weakSelf.setDefaultWatermark(firstWm, classifyList: list)
                }
            })
        }
    }
    
    func queryLastSelectedRecognitionType(completion: @escaping (WmcWatermarkDetailModel) -> Void) {
        let type: YPWmcManager.RecognitionWatermarkGroupType = YPWmcManager.shared.recognitionWatermarkGroupType
        
        var lastSelectedItem: WmcWatermarkDetailModel?
        
        if let json: String = WmcUserdefault.object(forKey: .Data.Recognition.lastSelectedItem) {
            lastSelectedItem = WmcWatermarkDetailModel.deserialize(from: json)
            if let item = lastSelectedItem {
                recognitionModel = item
                completion(item)
            }
        }
        
        WmcMediaWatermarkAPI.fetchWatermarkList(watermarkIds: type.info.templateIds, success: { [weak self] list in
            guard let weakSelf = self else { return }
            if !list.isEmpty {
                let dataSource = list[0].watermarks
                
                if !dataSource.isEmpty {
                    var result: WmcWatermarkDetailModel = dataSource[0]
                    
                    if lastSelectedItem != nil {
                        for (_, item) in dataSource.enumerated() {
                            if lastSelectedItem?.wmId == item.wmId {
                                result = item
                                break
                            }
                        }
                    } else {
                        if let json = result.toJSONString() {
                            WmcUserdefault.save(value: json, forKey: .Data.Recognition.lastSelectedItem)
                        }
                    }
                    
                    weakSelf.recognitionModel = result
                    completion(result)
                }
                WmcWatermarkListDBManager.insertClassifyList(templateGroupId: type.info.key, classifyList: list)
            }
        })
    }

    /// 设置默认水印
    func setDefaultWatermark(_ model: WmcWatermarkDetailModel,
                             classifyList: [WmcWatermarkClassifyModel])
    {
        var wmModel = model
        if let _wmModel = homeDelegate?.watermarkWillLoadDefault(.current,
                                                                 classifyList: classifyList,
                                                                 defaultWatermarkModel: model)
        {
            wmModel = _wmModel
        }
        setWatermarkModel(wmModel)
    }

    /// 设置水印
    func setWatermarkModel(_ model: WmcWatermarkDetailModel) {
        watermarkRelay.accept(model)
        // 标记最后一次使用的水印
        saveLastUseWatermark(model)
        // 设置水印回调
        homeDelegate?.watermarkDidChange(.current, model: model)
    }
    
    /// 设置水印，并将用户缓存数据保存
    /// 一般用于分享的水印进行数据缓存
    func setUserDataWatermarkModel(_ model: WmcWatermarkDetailModel) {
        // 存储用户编辑数据
        WmcUserEditWatermarksDBManager.insertWatermarkModel(model) { [weak self] _ in
            guard let weakSelf = self else { return }
            weakSelf.setWatermarkModel(model)
        }
    }

    /// 存储上一次使用的水印
    func saveLastUseWatermark(_ wm: WmcWatermarkDetailModel) {
        if let useSaveCache = homeDelegate?.watermarkLastSaveToCache(.current,
                                                                     watermarkModel: wm) {
            if useSaveCache {
                saveWatermark(wm)
            }
        } else {
            saveWatermark(wm)
        }

        func saveWatermark(_ wm: WmcWatermarkDetailModel) {
            guard let watermarkJsonStr = wm.toJSONString() else { return }
            WmcUserdefault.save(value: watermarkJsonStr,
                                forKey: .Data.lastUseWatermark())
        }
    }

    /// 搜索最后一次使用的水印
    func readLastUseWatermark(_ resultBlock: YPBlock.OneParam<WmcWatermarkDetailModel?>? = nil) {
        if let useReadCache = homeDelegate?.watermarkLastReadToCache(.current) {
            if useReadCache {
                readWatermark(resultBlock)
            }else{
                resultBlock?(nil)
            }
        } else {
            readWatermark(resultBlock)
        }

        func readWatermark(_ resultBlock: YPBlock.OneParam<WmcWatermarkDetailModel?>? = nil) {
            if let jsonStr: String = WmcUserdefault.object(forKey: .Data.lastUseWatermark()),
               let dic = jsonStr.wmc_jsonObj as? [String: Any]
            {
                let model = WmcWatermarkDetailModel.deserialize(from: dic)
                resultBlock?(model)
            } else {
                resultBlock?(nil)
            }
        }
    }
    

    /// 同步本地图片数据库列表
    func syncLocalAlbumList() {
        // 采取递归查找
        searchLocalAlbumList(list: []) { [weak self] result in
            guard let weakSelf = self else { return }
            weakSelf.localMediaAlbumPhotoListRelay.accept(result)
        }
    }

    func searchLocalAlbumList(page: Int = 1,
                              list: [WmcLocalMediaAlbumDBManager.DBModel],
                              resultBlock: @escaping YPBlock.OneParam<[WmcLocalMediaAlbumDBManager.DBModel]>)
    {
        var defaultTypes: [WmcMedia.MediaType] = [.image, .video]
        if let homeDelegate = homeDelegate {
            defaultTypes = homeDelegate.localAlbumLoadMediaType(.current, defaultMediaTypes: defaultTypes)
        }
        // 查询数据库表
        WmcLocalMediaAlbumDBManager.searchMediaData(page: page,
                                                    pageSize: 100) { [weak self] result in
            guard let weakSelf = self else { return }
            var dbList: [WmcLocalMediaAlbumDBManager.DBModel] = list
            for media in result {
                if dbList.count < 50 {
                    if defaultTypes.contains(media.mediaType) // 包含可选
                    {
                        dbList.append(media)
                    }
                } else {
                    break
                }
            }
            if page < 5, dbList.count < 50 {
                let newPage = page + 1 // 向后查找
                weakSelf.searchLocalAlbumList(page: newPage, list: dbList) { result in
                    resultBlock(result)
                }
            } else {
                resultBlock(dbList)
            }
        }
    }

    /// 同步云相册
    func registerPhotoSynchronization() {
        let networkType = YPNetworkReachability.queryNetworkReachabilityType()
        if networkType == .cellular || networkType == .ethernetOrWiFi {
            WmcUploadQueueManager.startAutoUploadTask()
        }

        YPNetworkReachability.monitoring().subscribe(onNext: { type in
            if type == .cellular || type == .ethernetOrWiFi {
                WmcUploadQueueManager.startAutoUploadTask()
            }
        }).disposed(by: rx.disposeBag)
    }

    func isLoginWithNewUser(completion: (Bool) -> Void) {
        if WmcLoginManager.shared.isLogin {
            return completion(true)
        }
        if let isShowed: Bool = WmcUserdefault.object(forKey: .Tips.Home.newUserRecodeMediaLoginFlag) {
            if isShowed {
                completion(true)
            } else {
                // pushLogin()
                WmcUserdefault.save(value: true, forKey: .Tips.Home.newUserRecodeMediaLoginFlag)
            }
        }
    }

    /// 新用户第一次拍照 （未登录）
    func newUserTakePhotoAlert() {
        guard YPWmcManager.shared.isIndependentPage else { return } // 只有独立包有
        let takePhotoNewUserLoginTip: Bool? = WmcUserdefault.object(forKey: .Alert.MoreRights.newUserTakePhotoFinish)
        if takePhotoNewUserLoginTip == nil, !WmcLoginManager.shared.isLogin {
            moreRightsRelay.accept(())
            WmcUserdefault.save(value: true, forKey: .Alert.MoreRights.newUserTakePhotoFinish)
        }
    }

    /// 新用户第一次拍视频弹窗（未登录）
    /// - Returns: description
    func newUserTakeVideoAlert() {
        guard YPWmcManager.shared.isIndependentPage else { return } // 只有独立包有
        let takePhotoNewUserLoginTip: Bool? = WmcUserdefault.object(forKey: .Alert.MoreRights.newUserTakePhotoFinish)
        if takePhotoNewUserLoginTip == nil, !WmcLoginManager.shared.isLogin {
            moreRightsRelay.accept(())
            WmcUserdefault.save(value: true, forKey: .Alert.MoreRights.newUserTakePhotoFinish)
        }
    }
    
    /// 是否显示云相册小红点
    /// - Parameter completion: 请求结果
    func fetchCloudAblumRedPoint(completion: @escaping (Bool) -> Void) {
        
        var isShow = true
        if let isShowed: Bool = WmcUserdefault.object(forKey: .Tips.Home.cloudAlbumNewUserGuideRedPoint) {
            isShow = !isShowed
        }
        
        if !WmcLoginManager.shared.isLogin {
            completion(isShow)
            return
        }

        WmcMediaTeamAlbumAPI.fetchTeamAlbumList().subscribe(onNext: { list in
            var hasDataList: [WmcMediaTeamAlbumModel] = []
            list.forEach { item in
                if item.maxDbId > 0 {
                    hasDataList.append(item)
                }
            }
            WmcCloudAlbumInfoDBManager.query { cacheList in
                if hasDataList.count > cacheList.count { // 接口返回的相册数量比缓存的多，则需要显示小红点
                    isShow = true
                } else if !hasDataList.isEmpty, !cacheList.isEmpty {
                    for (_, item) in hasDataList.enumerated() {
                        if isShow {
                            break
                        }
                        var isContain = false // 缓存中是否保存了该相册
                        for (_, cacheItem) in cacheList.enumerated() {
                            if item.albumId == cacheItem.albumId {
                                if item.maxDbId > cacheItem.maxDbId {
                                    isShow = true
                                    break
                                }
                                isContain = true
                            }
                        }
                        if !isContain {
                            isShow = true
                            break
                        }
                    }
                }
                completion(isShow)
            }
        }).disposed(by: rx.disposeBag)
    }
    
    /// 选择某个滤镜后调用
    func didSelected(filterItem: WmcImageFilterItem) {
        selectedFilterItem?.isSelected = false
        filterItem.isSelected = true
        selectedFilterItem = filterItem
    }
}
